# coding= utf-8

import requests
import json
import sys
import codecs
import warnings
import pymongo
import time

sys.stdout = codecs.getwriter('utf-8')(sys.stdout.detach())
warnings.filterwarnings("ignore")


class Keepa:
    def __init__(self):
        self.lr = {}
        self.api_prefix = 'https://api.keepa.com/product'
        self.api_current = ''
        # self.api_key1 = '2dk1l3e09o7hvjhcqg67lnrspsmmp3at0jikcsu9e8f257kstasjvev8thh0g1uv'
        # self.new_token = '6nokjd8r4ev0aq7ic6sktl1a1nc2a7l3eqr6k91l85qhtdkm1g9fvhmrbq8uapki'  # 新账户token
        self.api_key = 'r4mmbkscb3hgclav1f45dpg61tf0gga07eb91kbfqf253dl99d5jdvfkil1scvec'  # 付费token
        self.asset_url = 'https://m.media-amazon.com/images/I/'
        self.token_url = 'https://api.keepa.com/token'
        self.asin_list = []
        self.not_sale = []
        self.domain = ''
        self.locale = ''
        self.month = ''

        # 连接MongoDB
        # current_datetime = datetime.datetime.now()
        # current_year = current_datetime.year
        self.myclient = pymongo.MongoClient("mongodb://localhost:27017/")
        mydb = self.myclient["xp_analyse"]
        self.my_asin = mydb["wt_asin"]
        self.my_product = mydb["wt_product"]
        self.no_sale_asin = mydb["wt_asin_no_sale"]

    def get_asin(self, domain, asin):
        url = self.api_prefix
        params = {
            'key': self.api_current,
            'domain': int(domain),
            'asin': asin,
            'rating': 1,
            'stats': 180,
            'update': 6,
            'history': 0
        }
        response = requests.get(url=url, params=params)

        # 判断状态码
        status_code = response.status_code
        if not int(status_code) == 200:
            print('状态码：' + str(status_code) + '请求失败，等待下次重试！')
            self.myclient.close()
            exit()
        res = json.loads(response.text)

        # 请求成功添加至数据库
        my_list = []

        # 创建索引
        indexlist = self.my_product.index_information()
        if not indexlist:
            self.my_product.create_index("asin")
            self.my_product.create_index("month")
            self.my_product.create_index("country")

        # 判断请求是否成功
        if "error" in res:
            print(res['error']['message'])

        if "products" in res:
            for i in res['products']:
                # 判断没有价格、图片、分类树，略过
                if i['stats']['current'][1] < 0 or 'imagesCSV' not in i or i['imagesCSV'] == None or 'categoryTree' not in i:
                    # 不在售的asin则插入不在售表中
                    no_sale_item = dict([
                        ['month', self.month],
                        ['locale', translate_domain(int(self.domain))],
                        ['asin', i.get('asin', '')],
                        ['create_time', int(time.time())],
                    ])
                    exist = self.no_sale_asin.find_one({"locale": translate_domain(int(self.domain)), "asin": i.get('asin', '')})
                    if not exist:
                        self.not_sale.append(no_sale_item)
                    continue

                sales_rank_current = int(i['stats']['current'][3])
                reviews_review_count = int(i['stats']['current'][17])
                category = {}
                category_list = []

                if 'imagesCSV' in i and not i['imagesCSV'] == None:
                    image = i['imagesCSV'].split(',')[0]
                else:
                    image = ''
                if 'categoryTree' in i:
                    category_tree = i['categoryTree']
                else:
                    category_tree = ''
                if category_tree:
                    for tree in category_tree:
                        category[int(tree['catId'])] = tree['name']
                        category_list.append(tree['name'])
                    if i.get('salesRankReference', '') in category:
                        salesRankReference = category[int(i.get('salesRankReference', ''))]
                    else:
                        salesRankReference = int(i.get('salesRankReference', ''))
                else:
                    salesRankReference = ''

                # 获取父级分类ID和name
                if not category_tree == None:
                    parent_cate = category_tree[(len(category_tree) - 1)]
                else:
                    parent_cate = {
                        'catId': '',
                        'name': ''
                    }

                value = dict([
                    ['locale', translate_domain(int(self.domain))],
                    ['month', self.month],
                    ['domain_id', int(domain)],
                    ['category_id', parent_cate['catId']],
                    ['category_name', parent_cate['name']],
                    ['image', self.asset_url + image],
                    ['title', i.get('title', '')],
                    ['sales_rank_current', sales_rank_current],
                    ['sales_rank_reference', salesRankReference],
                    ['bought_in_past_month', i.get('monthlySold', '')],
                    ['reviews_rating', float(i['stats']['current'][16] / 10)],
                    ['reviews_review_count', reviews_review_count],
                    ['buy_box_current', float(i['stats']['current'][1] / 100)],
                    ['tracking_since', translate_time(int(i.get('trackingSince', '')))],
                    ['categories_tree', ' > '.join(category_list)],
                    ['asin', i.get('asin', '')],
                    ['create_time', int(time.time())],
                    ['update_time',  int(time.time())],
                ])
                my_list.append(value)

            # print(my_list)
            # exit()
            if len(my_list) > 0:
                result = self.my_product.insert_many(my_list)
                # 检查插入操作是否成功
                if result.acknowledged:
                    print('获取产品成功，共计' + str(len(my_list)) + '条！')
                else:
                    print('插入失败，等待下次重新获取！')
            else:
                print('暂无需要插入的数据！')

            # 插入不在售卖的asin集合
            if len(self.not_sale) > 0:
                no_sale_result = self.no_sale_asin.insert_many(self.not_sale)
                # 检查插入操作是否成功
                if no_sale_result.acknowledged:
                    print('插入不在售产品成功！，共计' + str(len(self.not_sale)) + '条！')
                else:
                    print('插入不在售产品失败！')

            # 标记已获取产品信息的asin
            if self.my_asin.update_many({'asin': {'$in': self.asin_list}, "country": self.locale}, {'$set': {'keepaed': True}}):
                print('标记已获取信息asin，共计' + str(len(self.asin_list)) + '条！')
            else:
                print('标记失败，等待下次标记！')
        else:
            print('返回结果无产品！')
        self.myclient.close()
        exit()

    def pre_asin(self):
        # 判断令牌剩余数量
        params = {
            'key': self.api_key
        }
        response = requests.get(url=self.token_url, params=params)
        res = json.loads(response.text)
        token_left = int(res['tokensLeft'])

        # 令牌不足退出
        if token_left < 300:
            print('Token不足， 剩余 ' + str(token_left))
            self.myclient.close()
            exit()
        else:
            self.api_current = self.api_key

        asins = self.my_asin.find({'keepaed': {'$exists': False}}).limit(100)
        asins_list = list(asins)
        asin_num = len(asins_list)
        if asin_num <= 0:
            self.myclient.close()
            print('Asin Is Complete!')
            exit()
        self.locale = asins_list[0]['country']
        self.month = asins_list[0]['month']
        self.domain = translate_locale(asins_list[0]['country'])
        for i in asins_list:
            if i['country'] == self.locale:
                self.asin_list.append(i['asin'])
        print('asin列表获取成功，国家为'+str(self.locale) + '， 共计:' + str(len(self.asin_list)))

        # 获取keepa产品信息
        if len(self.asin_list) > 0:
            asin = ','.join(self.asin_list)
            self.get_asin(self.domain, asin)
        else:
            self.myclient.close()
            print('Asin Is Complete!')
            exit()


def translate_domain(domain):
    dis = {1: 'us', 2: 'uk', 3: 'de', 4: 'fr', 5: 'jp', 6: 'ca', 8: 'it', 9: 'es', 10: 'in', 11: 'mx'}
    return dis.get(domain)


def translate_locale(domain):
    dis = {'us': 1, 'uk': 2, 'de': 3, 'fr': 4, 'jp': 5, 'ca': 6, 'it': 8, 'es': 9, 'in': 10, 'mx': 11}
    return dis.get(domain)


def translate_time(keepa_time):
    return (keepa_time + 21564000) * 60


keepa = Keepa()
keepa.pre_asin()
